
<!DOCTYPE html>
<html lang="en">
    <head>

    <title>ILRuntime中使用委托 — ILRuntime</title>
    <meta charset="utf-8">
    <meta name="description" content="ILRuntime">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

    <link rel="stylesheet" href="/ILRuntime/public/css/page.css">

    <script src="/ILRuntime/public/js/vue.js"></script>
    <script src="/ILRuntime/public/js/jquery.js"></script>
    </head>

    <body>
        
            <nav class="nav">
    <div class="border">
        <img src="/ILRuntime/public/images/logo.png" />
        <button class="hiden-in-phone">V1.4</button>
        <button id="btn-menu" class="hiden-in-pc">菜单</button>
        <ul class="nav-link hiden-in-phone">
            <!--li>
                <form id="search-form">
                    <input type="text" id="search-query" class="search-query">
                </form>
            </li!-->
            <li><a href="https://github.com/Ourpalm/ILRuntime" class="nav-link-li">下载项目</a></li>
            <li><a href="/ILRuntime/public/v1/guide/version.html" class="nav-link-li">更新记录</a></li>
            <li><a href="/ILRuntime/public/v1/guide/contribution.html" class="nav-link-li">贡献指南</li>
            <li><a href="/ILRuntime/public/v1/guide/index.html" class="nav-link-li">教程</a></li>
            <li><a href="/ILRuntime/public/" class="nav-link-li current">首页</a></li>
        </ul>
    </div>
</nav>

<div id="container" class="container clear">
    <section class="sidebar clearfix">
    <ul>
        
            
            
                <li><h3>基础</h3></li>
            
            
            
            <li>
                <p><a href="/ILRuntime/public/v1/guide/index.html" class="sidebar-link">介绍</a></p>
            </li>
        
            
            
            
            
            <li>
                <p><a href="/ILRuntime/public/v1/guide/version.html" class="sidebar-link">更新记录</a></p>
            </li>
        
            
            
            
            
            <li>
                <p><a href="/ILRuntime/public/v1/guide/contribution.html" class="sidebar-link">贡献指南</a></p>
            </li>
        
            
            
            
                <li><h3>教程</h3></li>
            
            
            <li>
                <p><a href="/ILRuntime/public/v1/guide/tutorial.html" class="sidebar-link">从零开始</a></p>
            </li>
        
            
            
            
            
            <li>
                <p><a href="/ILRuntime/public/v1/guide/delegate.html" class="sidebar-link current">ILRuntime中使用委托</a></p>
            </li>
        
            
            
            
            
            <li>
                <p><a href="/ILRuntime/public/v1/guide/cross-domain.html" class="sidebar-link">ILRuntime中跨域继承</a></p>
            </li>
        
            
            
            
            
            <li>
                <p><a href="/ILRuntime/public/v1/guide/reflection.html" class="sidebar-link">ILRuntime中的反射</a></p>
            </li>
        
            
            
            
            
            <li>
                <p><a href="/ILRuntime/public/v1/guide/redirection.html" class="sidebar-link">CLR重定向</a></p>
            </li>
        
            
            
            
            
            <li>
                <p><a href="/ILRuntime/public/v1/guide/bind.html" class="sidebar-link">CLR绑定</a></p>
            </li>
        
            
            
            
            
            <li>
                <p><a href="/ILRuntime/public/v1/guide/litjson.html" class="sidebar-link">LitJson集成</a></p>
            </li>
        
            
            
            
            
                <li><h3>其他</h3></li>
            
            <li>
                <p><a href="/ILRuntime/public/v1/guide/il2cpp.html" class="sidebar-link">IL2CPP打包注意事项</a></p>
            </li>
        
            
            
            
            
            <li>
                <p><a href="/ILRuntime/public/v1/guide/performance-optimization.html" class="sidebar-link">ILRuntime的性能优化</a></p>
            </li>
        
            
            
            
            
            <li>
                <p><a href="/ILRuntime/public/v1/guide/principle.html" class="sidebar-link">ILRuntime的实现原理</a></p>
            </li>
        
    </ul>
</section>
    <article class="clearfix">
    <h2 id="ILRuntime中使用委托"><a href="#ILRuntime中使用委托" class="headerlink" title="ILRuntime中使用委托"></a>ILRuntime中使用委托</h2><p>如果只在热更新的DLL项目中使用的委托，是不需要任何额外操作的，就跟在通常的C#里那样使用即可</p>
<p>如果你需要将委托实例传给ILRuntime外部使用，那则根据情况，你需要额外添加适配器或者转换器。<br>需要注意的是，一些编译器功能也会生成将委托传出给外部使用的代码，例如：</p>
<blockquote>
<p>Linq当中where xxxx == xxx，会需要将xxx == xxx这个作为lambda表达式传给Linq.Where这个外部方法使用<br>OrderBy()方法，原因同上</p>
</blockquote>
<p>如果在运行时发现缺少注册某个指定类型的委托适配器或者转换器时，ILRuntime会抛出相应的异常，根据提示添加注册即可。</p>
<h3 id="委托适配器（DelegateAdapter）"><a href="#委托适配器（DelegateAdapter）" class="headerlink" title="委托适配器（DelegateAdapter）"></a><strong>委托适配器（DelegateAdapter）</strong></h3><p>如果将委托实例传出给ILRuntime外部使用，那就意味着需要将委托实例转换成真正的CLR（C#运行时）委托实例，这个过程需要动态创建CLR的委托实例。由于IL2CPP之类的AOT编译技术无法在运行时生成新的类型，所以在创建委托实例的时候ILRuntime选择了显式注册的方式，以保证问题不被隐藏到上线后才发现。</p>
<blockquote>
<p>同一个参数组合的委托，只需要注册一次即可，例如：</p>
</blockquote>
<figure class="highlight csharp"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">delegate</span> <span class="keyword">void</span> <span class="title">SomeDelegate</span>(<span class="params"><span class="keyword">int</span> a, <span class="keyword">float</span> b</span>)</span>;</span><br><span class="line"></span><br><span class="line">Action&lt;<span class="keyword">int</span>, <span class="keyword">float</span>&gt; act;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>这两个委托都只需要注册一个适配器即可。 注册方法如下</p>
</blockquote>
<figure class="highlight csharp"><table><tr><td class="code"><pre><span class="line">appDomain.DelegateManager.RegisterMethodDelegate&lt;<span class="keyword">int</span>, <span class="keyword">float</span>&gt;();</span><br></pre></td></tr></table></figure>
<blockquote>
<p>如果是带返回类型的委托，例如：</p>
</blockquote>
<figure class="highlight csharp"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">delegate</span> <span class="keyword">bool</span> <span class="title">SomeFunction</span>(<span class="params"><span class="keyword">int</span> a, <span class="keyword">float</span> b</span>)</span>;</span><br><span class="line"></span><br><span class="line">Func&lt;<span class="keyword">int</span>, <span class="keyword">float</span>, <span class="keyword">bool</span>&gt; act;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>需要按照以下方式注册</p>
</blockquote>
<figure class="highlight csharp"><table><tr><td class="code"><pre><span class="line">appDomain.DelegateManager.RegisterFunctionDelegate&lt;<span class="keyword">int</span>, <span class="keyword">float</span>, <span class="keyword">bool</span>&gt;();</span><br></pre></td></tr></table></figure>
<h3 id="委托转换器（DelegateConvertor）"><a href="#委托转换器（DelegateConvertor）" class="headerlink" title="委托转换器（DelegateConvertor）"></a><strong>委托转换器（DelegateConvertor）</strong></h3><p>ILRuntime内部是使用Action,以及Func这两个系统自带委托类型来生成的委托实例，所以如果你需要将一个<code>不是Action或者Func类型</code>的委托实例传到ILRuntime外部使用的话，除了委托适配器，还需要额外写一个转换器，将Action和Func转换成你真正需要的那个委托类型。</p>
<p>比如上面例子中的SomeFunction类型的委托，其所需的Convertor应如下实现：<br><figure class="highlight csharp"><table><tr><td class="code"><pre><span class="line">app.DelegateManager.RegisterDelegateConvertor&lt;SomeFunction&gt;((action) =&gt;</span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> SomeFunction((a, b) =&gt;</span><br><span class="line">    &#123;</span><br><span class="line">       <span class="keyword">return</span> ((Func&lt;<span class="keyword">int</span>, <span class="keyword">float</span>, <span class="keyword">bool</span>&gt;)action)(a, b);</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p>
<h3 id="建议"><a href="#建议" class="headerlink" title="建议"></a><strong>建议</strong></h3><p>为了避免不必要的麻烦，以及后期热更出现问题，建议项目遵循以下几点：</p>
<ul>
<li>尽量<code>避免不必要的</code>跨域委托调用</li>
<li>尽量使用<code>Action以及Func</code>这两个系统内置万用委托类型</li>
</ul>

    <div class="footer">
        发现错误？想参与编辑？ 
        <a href="https://github.com/Ourpalm/ILRuntime/tree/master/docs/source/src/v1/guide/delegate.md" target="_blank">
            在 Github 上编辑此页！
        </a>
    </div>
</article>

<div class="sub-nav hiden-in-phone">
    <dl id="sub-nav">
        <dt>本文内容</dt>
        <dd v-for="(ele, index) in sub_nav">
           <a v-bind:href="ele.href">{{ ele.name }}</a>
        </dd>
    </dl>
</div> 
</div>

<footer>
    <div>
        <p>© Copyright 2017 Ourpalm All Rights Reserved</p>
        <p>掌趣科技2017</p>
    </div>
</footer>


<script>
var vm = new Vue({
    el : '#container',
    data: {
        sub_nav : [ ]
    },
    created:function(){
        var obj = [];
        $("article h3").each(function(){
            obj.push({name :  $(this).find("a").attr("title") , href : "#"+$(this).attr("id") });
        });

        this.sub_nav = obj;       
    }
});

var isShow = false;
$("nav").on("click","#btn-menu" , function(){

    if(!isShow){
        
        if($(document).scrollTop() > $(".sidebar").height() - 100){

            $('html, body').animate({scrollTop:0} , 300, "swing",function(){

                $(".sidebar").fadeIn();
                $(".container").animate({"left" : "15rem"}, 500,"swing");
            });
        }else{

                $(".sidebar").fadeIn();
                $(".container").animate({"left" : "15rem"}, 500,"swing");

        }

    }else{
        $(".sidebar").fadeOut();
        $(".container").animate({"left" : "0rem"}, 500,"swing");
    }
    isShow = !isShow;

});

$(".container").on("click" , "article" , function(){

    if(isShow){
        $(".sidebar").fadeOut();
        $(".container").animate({"left" : "0rem"}, 500,"swing");
        isShow = false;    
    }

});
</script>
        
    </body>
</html>